import javax.swing.JPanel;
import java.awt.event.*;
import java.awt.event.MouseAdapter;
import java.awt.*;
/**
 * Clase ActionListener que hereda de la interfaz MouseAdapter, para capturar
 * los eventos del mouse.
 * @version 2
 */
public class MouseListener extends MouseAdapter {
   private MyWorld world;
   private Drawable currentElement;
   private JPanel panel;
   public MouseListener (MyWorld w, JPanel p){
      world = w;
      panel = p;
   }
   /**
    * Función que calcula donde esta posicionado el puntero, para detectar si se
    * está sobre algún elemento para poder cambiar su posición y redibujar el panel.
    * @param e evento del mouse.
    */
   public void mouseMoved(MouseEvent e) {
      Drawable newElement = world.find(e.getX(), e.getY());
      if (newElement == currentElement) return;
      if (currentElement != null) {
         currentElement.setReleased();
         currentElement = null;
      }
      if (newElement != null) { 
         currentElement = newElement;
         currentElement.setSelected();
      }
      
      panel.repaint();
   }
   /**
    * Función que calcula donde esta posicionado el puntero, mientras arrastra
    * algún algún elemento para poder cambiar su posición y redibujar el panel.
    * @param e evento del mouse.
    */
   public void mouseDragged(MouseEvent e) {
      if (currentElement == null) return;
      currentElement.dragTo(e.getX(), e.getY());
      panel.repaint();
   }
   /**
    * Función al soltar el botón del mouse en el JPanel.
    * Si está en cursor en cruz, eliminará el elemento, de otra forma podrá
    * modificar los elementos del panel.
    * @param e evento del mouse.
    */
   public void mouseReleased(MouseEvent e) {
      if (world.isBorrar()) {
        world.delElement(e.getX(), e.getY());
        return;
      }
       
      if (currentElement != null) 
         currentElement.setReleased();
     
      if (currentElement instanceof GSpring) {
        // we dragged an attachable element
        // we dragged a spring, so we look for and attachable element near by  
        AttachableElement element = world.findAttachableElement(e.getX(), e.getY());
        if (element == null) {
            currentElement = null;
            return;
        }
        // we dragged a spring and it is near an attachable element,
        // so we hook them to the right spring end.
        GSpring spring = (GSpring) currentElement;
        Vector2D a=spring.getAendPosition();
        if ((a.getX()==e.getX()) && (a.getY()==e.getY()))
            spring.attachAend(element);
        Vector2D b=spring.getBendPosition();
        if ((b.getX()==e.getX()) && (b.getY()==e.getY()))
            spring.attachBend(element);
      }
      
      if (currentElement instanceof GRubberBand) {
        // we dragged an attachable element
        // we dragged a spring, so we look for and attachable element near by  
        AttachableElement element = world.findAttachableElement(e.getX(), e.getY());
        if (element == null) {
            currentElement = null;
            return;
        }          
        // we dragged a rubber and it is near an attachable element,
        // so we hook them to the right rubber end.
        GRubberBand rubber = (GRubberBand) currentElement;
        Vector2D a=rubber.getAendPosition();
        if ((a.getX()==e.getX()) && (a.getY()==e.getY()))
            rubber.attachAend(element);
        Vector2D b=rubber.getBendPosition();
        if ((b.getX()==e.getX()) && (b.getY()==e.getY()))
            rubber.attachBend(element);
      }
      currentElement = null;
      panel.repaint();      
   }
}